﻿using System;
using System.Web.Mvc;
using System.Web.UI;
using App.Account.Models;
using App.Account.Models.Forms;
using App.Account.Services;
using App.Utility.Controllers;
using App.Utility.Pathing;
using App.Utility.Services;
using StructureMap;
using App.Utility.Paging;
using System.Linq;
using System.Collections.Generic;

namespace App.Account.Controllers
{

    [HandleError]
    [OutputCache(Location = OutputCacheLocation.None)]
    public class AccountAdminController : Controller
    {
        IAccountService accountService;

        public AccountAdminController()
        {
             accountService = ObjectFactory.GetInstance<IAccountService>();
        }


        [Authorize(Roles="Admin")]
        public ActionResult Index()
        {
            ViewData["Title"] = "Account Admin Home";
            ViewData["Message"] = "Welcome to the account admin";

            return this.PluginView();
        }

        [Authorize(Roles = "Admin")]
        public ActionResult DeleteUserWithPage(int? page, Guid UserID)
        {
            User user = accountService.GetUser(UserID);
            if (user != null)
                accountService.DeleteUser(user);
            return RedirectToAction("Users", page);
        }


        [AcceptVerbs("GET")]
        [Authorize(Roles = "Admin")]
        public ActionResult EditUser(Guid? UserID)
        {
            User user = null;
            UserForm form = new UserForm { };
            if (UserID.HasValue)
            {
                user = accountService.GetUser(UserID.Value);
                if (user == null)
                    return RedirectToAction("Users");

                form = new UserForm
                {
                    Email = user.Email,
                    Password = user.Password,
                    UserID = user.ID,
                    UserName = user.Name,
                    Roles = user.Roles.Select(r => r.ID).ToList()
                };
            }
            else
            {
                form = new UserForm { Roles = new System.Collections.Generic.List<Guid>() };
            }

            ViewData["AllRoles"] = accountService.GetRolePage(new PageRequest(0, 50,"Name", typeof(string),true)).Page.ToArray();
            ViewData.Model = form;

            return this.PluginView();
        }


        [AcceptVerbs("POST")]
        [Authorize(Roles = "Admin")]
        public ActionResult EditUser(Guid? UserID, [Bind(Include="UserID,UserName,Email,Password,Roles",Prefix="")] UserForm form)
        {
            //ViewData["Title"] = "Edit User";
            //ViewData["Message"] = "";

            User user = null;
            if (UserID.HasValue)
            {
                user = accountService.GetUser(UserID.Value);
                if (user == null)
                    return RedirectToAction("Users");
            }
            else
                form.Roles = new System.Collections.Generic.List<Guid>();

            ServiceResponse<User> response = accountService.AttemptUserEdit(form);

            if (response.Successful)
            {
                TempData["Message"] = "Update Successfull";
                if (UserID == null)
                    return RedirectToAction("EditUser", new { UserID = response.Response.ID });
            }
            else
            {
                this.UpdateModelStateWithViolations(response.RuleViolations);
            }

            if(form.Roles==null)
                form.Roles = new System.Collections.Generic.List<Guid>();

            ViewData["AllRoles"] = accountService.GetRolePage(new PageRequest(0, 50, "Name", typeof(string), true)).Page.ToArray();

            ViewData.Model = form;

            return this.PluginView();
        }



        [Authorize(Roles = "Admin")]
        public ActionResult Users(int? page)
        {

            ViewData["Title"] = "Account Admin : User Manager";

            PagingSet Paging = PagingSet.DefaultConfiguration();
            Paging.FilterFields = new ContractList<string> { "Name", "Email" };
            Paging.SortableFields = new ContractList<string> { "Name", "Email" };
            Paging.SortableFieldTypes = new ContractList<string> { typeof(string).Name, typeof(string).Name };
            Paging.FilterableFieldTypes = new ContractList<string> { typeof(string).Name, typeof(string).Name };
            ViewData["PagingSet"] = Paging;

            PageResponse<User> response = accountService.GetUserPage(
                Paging.ParsePagingQueryStringToPageRequest(page, 10, HttpContext));
            
            
            if ((response.PageIndex > 0 && response.Page.Count == 0) || (page ?? 1) < 1)
                return RedirectToAction("Users");
            ViewData.Model = response;


            return this.PluginView();
        }




        [Authorize(Roles = "Admin")]
        public ActionResult DeleteUser(Guid ID)
        {
            App.Account.Models.User user = accountService.GetUser(ID);
            if (user != null)
                accountService.DeleteUser(user);
            return RedirectToAction("Users", new { ID = ID });
        }





        [Authorize(Roles = "Admin")]
        public ActionResult Roles(int? page)
        {

            ViewData["Title"] = "Account Admin : Role Manager";

            PagingSet Paging = PagingSet.DefaultConfiguration();
            Paging.FilterFields = new ContractList<string> { "Name", "Level" };
            Paging.SortableFields = new ContractList<string> { "Name", "Level" };
            Paging.SortableFieldTypes = new ContractList<string> { typeof(string).Name, typeof(int).Name };
            Paging.FilterableFieldTypes = new ContractList<string> { typeof(string).Name, typeof(int).Name };

            ViewData["PagingSet"] = Paging;

            PageResponse<Role> response = accountService.GetRolePage(
                Paging.ParsePagingQueryStringToPageRequest(page, 10, HttpContext));


            if ((response.PageIndex > 0 && response.Page.Count == 0) || (page ?? 1) < 1)
                return RedirectToAction("Roles");
            ViewData.Model = response;

            return this.PluginView();
        }



        [Authorize(Roles = "Admin")]
        public ActionResult DeleteRole(Guid ID)
        {
            App.Account.Models.Role role = accountService.GetRole(ID);
            if (role != null)
                accountService.DeleteRole(role);
            return RedirectToAction("Roles", new { ID = ID });
        }



        [Authorize(Roles = "Admin")]
        public ActionResult DeleteRoleWithPage(int? page, Guid RoleID)
        {
            Role role = accountService.GetRole(RoleID);
            if (role != null)
                accountService.DeleteRole(role);
            return RedirectToAction("Roles", page);
        }




        [AcceptVerbs("GET")]
        [Authorize(Roles = "Admin")]
        public ActionResult EditRole(Guid? RoleID)
        {
            Role role = null;
            RoleForm form = new RoleForm { };
            if (RoleID.HasValue)
            {
                role = accountService.GetRole(RoleID.Value);
                if (role == null)
                    return RedirectToAction("Roles");

                form = new RoleForm
                {
                    RoleID = role.ID,
                    RoleName = role.Name,
                    Level = role.Level
                };
            }
            else
            {
                form = new RoleForm();
            }

            ViewData.Model = form;

            return this.PluginView();
        }


        [AcceptVerbs("POST")]
        [Authorize(Roles = "Admin")]
        public ActionResult EditRole(Guid? RoleID, [Bind(Include = "RoleID,RoleName,Level", Prefix = "")] RoleForm form)
        {
            Role role = null;
            if (RoleID.HasValue)
            {
                role = accountService.GetRole(RoleID.Value);
                if (role == null)
                    return RedirectToAction("Roles");
            }

            ServiceResponse<Role> response = accountService.AttemptRoleEdit(form);

            if (response.Successful)
            {
                TempData["Message"] = "Update Successfull";
                if (RoleID == null)
                    return RedirectToAction("EditRole", new { RoleID = response.Response.ID });
            }
            else
            {
                this.UpdateModelStateWithViolations(response.RuleViolations);
            }

            //ViewData["AllRoles"] = accountService.GetRolePage(new PageRequest(0, 50, "Name", typeof(string), true)).Page.ToArray();

            ViewData.Model = form;

            return this.PluginView();
        }
    }
}
